Snowflake×dbtを試してみた~Part5:テスト&Doc&デプロイ編~ #SnowflakeDB #dbt
※本エントリは、Snowflakeをより使いこなそう! Advent Calendar 2021の23日目の記事となります。
さがらです。
Snowflake公式のdbtと連携した時の機能を一通り試すことが出来るQUICKSTARTSに関して試してみた内容をまとめていきます。※この記事は「Part5:テスト&Doc&デプロイ編」となります。
この記事の内容について
Snowflake公式のQUICKSTARTSに、Accelerating Data Teams with dbt & SnowflakeというSnowflakeとdbtを組み合わせたときの利点を一通り試すことが出来るクイックスタートがあります。
こちらの内容について、以下の合計5本の構成で試してみた内容を書いていきます。
- Part1:基本設定編
- 「1.Overview」から「5. dbt Configuration」
- Part2:Project設定編
- 「6. dbt Project Configuration」
- Part3:パイプライン構築編その1
- 「7. Building dbt Data Pipelines」から「9. dbt pipelines - Intermediate」
- Part4:パイプライン構築編その2
- 「10. dbt pipelines - Seeds」から「12. dbt pipelines - Facts」
- Part5:テスト&Doc&デプロイ編 ※この記事です。
- 「13. dbt pipelines - Tests & Docs」から「16. Appendix」
この記事では、「テスト&Doc&デプロイ編」ということで「13. dbt pipelines - Tests & Docs」から「16. Appendix」の内容についてまとめていきます。
13. dbt pipelines - Tests & Docs
ここでは、dbtを用いたテストとドキュメントについて見ていきます。
組織でデータ活用をするにあたり、データに対する信頼を築くには、テストとドキュメンテーションを整備しておくことはやはり重要です。テストの自動化とドキュメンテーションに関する方法は数多くありますが、dbtには標準機能として、データテストとドキュメンテーションの機能が備わっております。
dbtを用いたテストの定義・実行
dbtにおけるテストは、以下の4つに関するテストを提供しています。
- uniqueness(値の一意であること)
- not_null(値がNULLでないこと)
- check constraints(値が条件を満たしていること)
- relationship integrity(リレーションを作成した2つのテーブル間で、整合性があること ※参照整合性のこと)
早速、テストに関する定義をしていきましょう。
New File
から、名前をmodels/marts/core/intermediate/intermediate.yml
に書き換えて、新しくファイルを作成します。
intermediate.yml
ファイルが出来たら、以下の内容をコピーして貼り付けて、右上のsave
を押します。
version: 2 models: - name: int_fx_rates description: "An intermediate model that filters stg_knoema_fx_rates" columns: - name: currency||exchange_date tests: - unique - not_null - name: int_unioned_book description: "An intermediate model unions the manual_book csvs" columns: - name: instrument tests: - not_null - relationships: to: ref('int_knoema_stock_history') field: company_symbol - name: int_knoema_stock_history description: "An intermediate model that pivots the stg_knoema_stock_history model by indicator" columns: - name: company_symbol||stock_date tests: - not_null - unique
早速テストをしてみます!コマンドラインでdbt test
と入力し、実行してください。
そしてログを見ると、not_null_my_first_dbt_model_id
とunique_int_knoema_stock_history_company_symbol_stock_date
においてテストが失敗していることがわかるはずです。
この内、unique_int_knoema_stock_history_company_symbol_stock_date
について詳しく見ていきます。
対象項目のDetails
を押すと、テストとして失敗したクエリが表示されます。
ここで、以下のクエリを貼り付けて、スキーマ名を自身のものに変更した上で、Preview
を押してください。※スキーマ名を変更する箇所が2つあるので注意してください。
with cst as ( select company_symbol||stock_date as conctat from <dev_schema>_marts.int_knoema_stock_history where company_symbol||stock_date is not null group by company_symbol||stock_date having count(*) > 1 limit 1 ) select * from <dev_schema>_marts.int_knoema_stock_history where company_symbol||stock_date IN (SELECT conctat FROM cst)
このクエリは、テストに指定したキーがユニークであるかどうかを確かめるために実行したのですが、下図の結果の通り、テストに指定したユニークキーで2レコード以上存在するレコードがあったようです。この確認により、stock_exchange_name
もユニークキーとして指定しなければいけないことがわかりました。
intermediate.yml
ファイルを開いて、内容を下記に書き換えてください。変更点としては、int_knoema_stock_history
modelのところで、|| stock_exchange_name
と追加しています。
version: 2 models: - name: int_fx_rates description: "An intermediate model that filters stg_knoema_fx_rates" columns: - name: currency||exchange_date tests: - unique - not_null - name: int_unioned_book description: "An intermediate model unions the manual_book csvs" columns: - name: instrument tests: - not_null - relationships: to: ref('int_stock_history') field: company_symbol - name: int_knoema_stock_history description: "An intermediate model that pivots the stg_knoema_stock_history model by indicator" columns: - name: company_symbol||stock_date||stock_exchange_name tests: - not_null - unique
ここで、1つ私の考えを記しておきます…
今回はクイックスタートに沿って実施しているだけですが、「データに合わせてテストの内容を変更する」というのは基本NGだと私は考えています。「テストが上手く通らないなら、テストの条件を変えてしまえ!」と言っているようなものですからね…。
今回の例でいうと、ユニークキーのテストケースを書き換える理想形としては、以下の流れが良いと考えています。
- 事前の処理設計でユニークキーを明確にしておく
- そのユニークキーをテストとして実装
- その後テストでエラーが発生したら、データ自体に異常がないかを疑い、調査をする(原因の例:DWHへの重複ロード、など)
- データ自体に異常がないことを確認した上で、事前のユニークキー処理設計が間違えていたことを認識し、テストの内容を書き換える
余談でしたが、テストは厳密に行わないと意味がないため、補足させて頂きました。
では改めて、テストを実行してみましょう!
コマンドラインにdbt test -m int_knoema_stock_history
と入力し、実行してください。
下図の通り、先程エラーになったunique_int_knoema_stock_history_company_symbol_stock_date_stock_exchange_name
がpassしていればOKのです!
dbtを用いたドキュメント生成
以前の章でも一度ドキュメントは生成していましたが、一通りmodelの定義を終えた現段階で改めてmodelを作成してみます。
コマンドラインで、dbt docs generate
を実行して、生成されてドキュメントをview docs
から開いてみてください。
ここで、これまでに生成したmodelについてのドキュメントを少し見てみます。
以下は先程テストでも確認したint_knoema_stock_history
についてのドキュメントですが、Description
にAn intermediate model that pivots the stg_knoema_stock_history model by indicator
と記されているのがわかります。
実は先程作成したテストの中にdescription
というパラメータがあり、この内容がドキュメントに適用されているのです。
dbtのドキュメントは、別のMarkdownファイルも参照させることで各カラムの定義を表に起こすことも可能です。ドキュメントについてより詳しく知りたい場合はこちらの記事も併せてご覧ください。
不要なデフォルトモデルの削除
先程のテスト結果でお気づきの方もいるかもしれませんが、example
フォルダの中にあるmodelがあると、テストはエラーを出してしまいます。
そのため、example
フォルダを削除しておきましょう。
example
フォルダの横の「・・・」を押して、Delete
を押し、確認画面ではConfirm
を押しましょう。
開発内容のCommit
ここまで完了したら、一通りの開発作業は終わりのため、内容をCommitしておきましょう。Commit Messageはset up test for intermediate models
のような文言を入れておきましょう。
14. dbt pipelines - Deployment
これまでの工程で、パイプラインの開発、テスト、文書化など、一通り開発を行ってきました。
…が、これは別途切ったブランチ上での作業のため、まだ本番環境には何も影響を与えていません。 そこで、GitリポジトリのMasterブランチにマージして本番環境での実行設定を行う、デプロイ作業を行います。
Masterブランチへのマージ
13章の最後でCommitしていれば、左上には下図のようにmerge to master
と表示されているはずです。
一定時間後、下図のように、`branch: master(read-only)と表示されるはずです。これで、Masterブランチへこれまで開発した内容の適用(マージ)が完了しました!
本番環境へ適用させるための設定変更
続いて、本番環境へ適用させるための各種設定を行っていきます。(今回のクイックスタートではSnowflakeのPartner Connectを用いているので、少し設定を変更するだけで充分です。)
左上のメニューバーからEnvironments
をクリックします。
続いて、Deplpyment
➟右上のSettings
と続けてクリックします。
ここでは、Deploy時に適用されるスキーマ名を変更していきます。(デフォルトだとdbt_の形だと思います。)この場では本番環境のスキーマをproduction
とし、変更していきます。本番環境のスキーマを明確に分けて置くことで、開発環境と混同せずに済みます。
右上のEdit
を押してください。
Deployment Credentials
のSCHEMA
を、production
に変更した上で、Save
を押してください。
ジョブの設定
最後に、ジョブの設定をしていきます。
左上のメニューバーから、Jobs
をクリックします。
続いて、Partner Connectにより自動で作られたジョブPartner Connect Trial Job
をクリックし、右上のSettings
を押します。
ジョブの設定値が表示されますので、編集するために右上のEdit
を押します。
まず、ジョブのNAME
をProduction Job
に変更します。これが本番稼動のジョブであることを名前から明示的にしておきます。
続いて、THREADS
の値を8
に変更します。この変更により、dbtはDAG内の8つのdbtモデルを依存関係なしに同時に実行することができるようになります。8
は、Snowflakeで推奨されるデフォルトです。(クイックスタートの記載をそのまま引用しています。)
他の設定は変更しませんが、どんな設定ができるかを少し見ておきたいと思います。
まず、Commands
ではこのジョブによりどのコマンドが実行されるかを順番付きで指定可能です。dbt seed
によりcsvからデータをロードし、dbt run
でmodelを一通り実行、dbt test
でテストを実行する、という一連の流れが設定されています。
続いて、Triggers
ではこのジョブを何をトリガーにして実行するかを設定できます。自動実行させたい場合には必須のオプションですね。この場では手動でジョブを実行するためどのオプションも有効にしません。
ここまで、設定が終わったら右上のSave
を押してください。
続いて、Settingsよりひとつ上の階層に戻り、Run now
を押してこのジョブを実行します。
少し時間がかかると思います。終了後、実行したジョブを一覧から選択すると、どのような処理が行われたかを詳細に確認可能となっています。
15. Conclusion & Next Steps
dbtとSnowflakeを使用して、分析のためのデータ変換パイプラインを構築する方法を学びました。
- dbtとSnowflakeのセットアップ方法
- Snowflakeのデータマーケットプレイスでデータを活用する方法
- dbtプロジェクトの実行とパイプラインの開発方法
- データテストとドキュメントの作成方法
引き続き無料トライアルを続けて、ご自身のサンプルデータや本番データをロードし、dbt CloudとSnowflakeのより高度な機能にトライしていきましょう!
更にdbtを知るためには、以下のコンテンツがオススメです。
- Slackのdbt community:この記事でも紹介したとおり、全世界2万人を超えるユーザーが在籍しているコミュニティです。
- 公式のトレーニング:英語にはなりますが、無料の学習コンテンツがありますのでそれを用いて学習することも可能です。
- DevelopersIOのdbt記事:(これは公式には載っていないですが…笑)このDevelopersIOにおいても、多くのdbtの記事を執筆しておりますのでぜひご覧ください!
16. Appendix
ここでは、dbtで構築したデータの活用ということで、Snowflakeの可視化機能「Snowsight」を用いた可視化について少しだけ触れています。
Snowsightの画面から以下のクエリを実施すると、dbtで加工したデータを元に可視化することが出来ます。
select * from pc_dbt_db.<dev_schema>_marts.int_daily_position_with_trades where trader = 'Tina M.' order by book_date
これはほんの一例ですが、dbtを用いてBIツールで可視化しやすいようにデータを加工➟BIツールで可視化という流れでdbtを使うことはとても良いユースケースだと思います。ぜひ、SnowsightでもOKですが、他のBIツールと組み合わせてdbtで加工した結果を可視化してみてください!!
次回
Snowflakeをより使いこなそう! Advent Calendar 2021、次回の24日目では、「Snowflake×dbt特有の設定をまとめてみる」というタイトルで執筆します。お楽しみに!